package org.pan.service.impl;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.pan.domain.PageParameter;
import org.pan.domain.PageResult;
import org.pan.domain.db.*;
import org.pan.service.SystemService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 系统用户角色菜单service实现
 * Created by Administrator on 2015/11/10.
 */
public class SystemServiceImpl extends AbstractService implements SystemService {

    public final Logger LOGGER = LoggerFactory.getLogger(SystemServiceImpl.class);

    @Transactional
    @Override
    public Long saveSystemRole(SystemRole systemRole) {
        LOGGER.debug("保存系统角色");
        getHibernateTemplate().saveOrUpdate(systemRole);
        return systemRole.getId();
    }

    @Transactional
    @Override
    public Long saveSystemMenu(SystemMenu systemMenu) {
        LOGGER.debug("保存系统菜单");
        getHibernateTemplate().saveOrUpdate(systemMenu);
        return systemMenu.getId();
    }

    @Transactional
    @Override
    public Long saveSystemAccount(SystemAccount systemAccount) {
        LOGGER.debug("保存系统登录账户");
        getHibernateTemplate().saveOrUpdate(systemAccount);
        return systemAccount.getId();
    }

    @Override
    public SystemRole getSystemRoleById(Long roleId) {
        LOGGER.debug("根据id查询系统角色");
        return getHibernateTemplate().get(SystemRole.class,roleId);
    }

    @Override
    public SystemMenu getSystemMenuById(Long menuId) {
        LOGGER.debug("根据id查询系统菜单");
        return getHibernateTemplate().get(SystemMenu.class,menuId);
    }

    @Override
    public SystemAccount getSystemAccountById(Long accountId) {
        LOGGER.debug("根据id查询系统角色");
        return getHibernateTemplate().get(SystemAccount.class,accountId);
    }

    @Override
    public Set<SystemMenu> getSystemMenuListByRoleId(Long roleId) {
        LOGGER.debug("根据角色id查询拥有菜单");
        return getHibernateTemplate().get(SystemRole.class,roleId).getSystemMenuSet();
    }

    @Override
    public Set<SystemMenu> getSystemMenuListByAccountId(Long accountId) {
        LOGGER.debug("根据账户id查询拥有菜单");
        SystemAccount systemAccount = getHibernateTemplate().get(SystemAccount.class, accountId);
        List<SystemRole> hasRoleList = systemAccount.getSystemRoleList();
        Set<SystemMenu> hasMenuList = new HashSet<>();
        hasRoleList.parallelStream().forEach(role->hasMenuList.addAll(role.getSystemMenuSet()));
        return hasMenuList;
    }

    @Override
    public Set<SystemMenu> getSystemMenuList() {
        LOGGER.debug("获取所有系统菜单");
        List<SystemMenu> systemMenus = getHibernateTemplate().loadAll(SystemMenu.class);
        return systemMenus.stream().collect(Collectors.toSet());
    }

    @Override
    public PageResult getSystemRolePageList(PageParameter pageParameter) {
        LOGGER.debug("获取系统角色分页列表");
        DetachedCriteria findCriteria = DetachedCriteria.forClass(SystemRole.class);

        DetachedCriteria countCriteria = DetachedCriteria.forClass(SystemRole.class);
        countCriteria.setProjection(Projections.rowCount());

        return createPageResult(pageParameter.getPage(),pageParameter.getPageSize(),findCriteria,countCriteria);
    }

    @Override
    public PageResult getSystemAccountPageList(PageParameter pageParameter) {
        LOGGER.debug("获取系统账户分页列表");
        DetachedCriteria findCriteria = DetachedCriteria.forClass(SystemAccount.class);

        DetachedCriteria countCriteria = DetachedCriteria.forClass(SystemAccount.class);
        countCriteria.setProjection(Projections.rowCount());

        return createPageResult(pageParameter.getPage(),pageParameter.getPageSize(),findCriteria,countCriteria);
    }


    @Transactional
    @Override
    public void updateSystemRoleMenu(Long roleId, List<Long> menuIdList) {
        LOGGER.debug("修改系统角色拥有菜单");
        SystemRole systemRole = getHibernateTemplate().get(SystemRole.class, roleId);
        systemRole.setSystemMenuSet(Collections.emptySet());
        getHibernateTemplate().flush();

        Set<SystemMenu> systemMenuSet = menuIdList.parallelStream().map(menuId -> getHibernateTemplate().load(SystemMenu.class, menuId)).collect(Collectors.toSet());
        systemRole.setSystemMenuSet(systemMenuSet);
    }

    @Transactional
    @Override
    public void updateSystemAccountRole(Long accountId, List<Long> roleIdList) {
        LOGGER.debug("更新系统账户拥有角色");
        SystemAccount systemAccount = getHibernateTemplate().get(SystemAccount.class, accountId);
        systemAccount.setSystemRoleList(Collections.emptyList());
        getHibernateTemplate().flush();

        List<SystemRole> systemRoleList = roleIdList.parallelStream().map(roleId -> getHibernateTemplate().load(SystemRole.class, roleId)).collect(Collectors.toList());
        systemAccount.setSystemRoleList(systemRoleList);
    }

    @Transactional
    @Override
    public void removeSystemRole(Long roleId) {
        LOGGER.debug("根据id删除系统角色");
        SystemRole systemRole = getHibernateTemplate().load(SystemRole.class, roleId);
        getHibernateTemplate().delete(systemRole);
    }

    @Transactional
    @Override
    public void removeSystemMenu(Long menuId) {
        LOGGER.debug("根据id删除系统菜单");
        SystemMenu systemMenu = getHibernateTemplate().load(SystemMenu.class, menuId);
        getHibernateTemplate().delete(systemMenu);
    }

    @Transactional
    @Override
    public void removeSystemAccount(Long accountId) {
        LOGGER.debug("根据id删除系统账户");
        SystemAccount systemAccount = getHibernateTemplate().load(SystemAccount.class, accountId);
        getHibernateTemplate().delete(systemAccount);
    }
}
